package com.lyd.sweet.mybatis.utils;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lyd.sweet.model.BaseQueryDTO;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 分页查询工具
 *
 * @author 木木
 **/
public class PageUtil {

    /**
     * 下划线字符串分割符
     */
    private final static String UNDER_LINE_CHAR = "_";

    /**
     * order by
     */
    private final static String ORDER_BY_SPLIT_CHAR = " ";


    /**
     * 构建分页返回结果（包含具体数据）
     *
     * @param page 分页信息
     * @param data 具体数据
     * @return 构建分页返回对象
     */
    public static <T> PageInfo<T> buildResult(Page page, List<T> data) {
        PageInfo<T> result = new PageInfo<>();
        result.setList(data);
        result.setPageSize(page.getPageSize());
        result.setPageNum(page.getPageNum());
        result.setTotal(page.getTotal());
        result.setStartRow(page.getStartRow());
        result.setEndRow(page.getEndRow());
        result.setPages(page.getPages());
        return result;
    }

    /**
     * 构建分页查询page对象，用与生成sql语句中limit，排序等信息
     * 不要用pagehelp的orderby 会造成sql注入
     *
     * @param baseQueryDTO 基础查询对象
     * @return 分页查询对象
     */
    public static Page buildQueryPage(BaseQueryDTO baseQueryDTO) {
        final int minPageNum = 1;
        final int defaultSize = 10;
        final int minSize = 1;
        if (baseQueryDTO.getPage() < minPageNum) {
            baseQueryDTO.setPage(minPageNum);
        }
        if (baseQueryDTO.getSize() < minSize) {
            baseQueryDTO.setSize(defaultSize);
        }
        Page page = PageHelper.startPage(baseQueryDTO.getPage(), baseQueryDTO.getSize());
        PageUtil.orderBySQLProcessor(baseQueryDTO);
        page.setUnsafeOrderBy(baseQueryDTO.getOrderBy());
        return page;
    }

    /**
     * order by sql 语句处理器
     *
     * @param baseQueryDTO
     */
    public static void orderBySQLProcessor(BaseQueryDTO baseQueryDTO) {
        // 将驼峰字段转成下划线
        String orderBy = baseQueryDTO.getOrderBy();
        String sortStr = Boolean.TRUE.equals(baseQueryDTO.getDesc()) ? "DESC" : "ASC";
        if (!StringUtils.isEmpty(orderBy)) {
            final String orderBySplit = ",";
            String[] orderByArr = orderBy.split(orderBySplit);
            String[] newOrderArr = new String[orderByArr.length];
            for (int i = 0; i < orderByArr.length; i++) {
                newOrderArr[i] = upCaseToUnderLine(orderByArr[i]) + ORDER_BY_SPLIT_CHAR + sortStr;
            }
            baseQueryDTO.setOrderBy(String.join(orderBySplit, newOrderArr));
        }
    }


    /**
     * 驼峰转下划线
     *
     * @param str 代转换字符串
     * @return 转换之后的下划线字符串
     */
    private static String upCaseToUnderLine(String str) {
        StringBuilder res = new StringBuilder(str.length());
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (ch >= 'A' && ch <= 'Z') {
                res.append(UNDER_LINE_CHAR);
                res.append(String.valueOf(str.charAt(i)).toLowerCase());
            } else {
                res.append(ch);
            }
        }
        return res.toString();
    }
}
